/**
 * 
 */
package cn.edu.nju.ws.sview.wyge.relations.adataset;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import cn.edu.nju.ws.sview.cache.URIIDCache;
import cn.edu.nju.ws.sview.database.DBConnectionFactory;
import cn.edu.nju.ws.sview.wyge.util.Util;

/**
 * @author Weiyi Ge (geweiyi@gmail.com) 2012-8-20
 * 
 */
public class BasicTriplePattern {
	private ArrayList<Integer> docs;

	public BasicTriplePattern(ArrayList<Integer> docs) {
		this.docs = docs;
	}
	public int getObjectPropNum(){
		int objectPropNum = 0;
		String cs = "";
		for (int d : docs) {
			cs += d + ",";
		}
		cs = cs.substring(0, cs.length() - 1);

		int typeid = 0;
		try {
			typeid = URIIDCache.getInstance().getURIID(
					"http://www.w3.org/1999/02/22-rdf-syntax-ns#type", false);
		} catch (Throwable e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		try {
			Connection conn = DBConnectionFactory.getConnection();// .getFalconConnection();
			PreparedStatement selpps = conn.prepareStatement("SELECT count(distinct p) FROM quadruple where doc_id in (?) and p!=? and o like 'u%'");
			selpps.setString(1, cs);
			selpps.setString(2, "u"+typeid);
			ResultSet selprs = selpps.executeQuery();
			if(selprs.next()){
				objectPropNum = selprs.getInt(1);
			}
//			PreparedStatement selclassps = conn
//					.prepareStatement("SELECT count(distinct p,o) FROM quadruple where doc_id in (?) and p='u"
//							+ typeid + "' and o like 'u%';");
//			selclassps.setString(1, cs);
//			ResultSet selclassrs = selclassps.executeQuery();
//			if(selclassrs.next()){
//				objectPropNum += selclassrs.getInt(1);
//			}
			selprs.close();
			selpps.close();

			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return objectPropNum;
	}
	public int getTotalNum(){
		int totalNum = 0;
		String cs = "";
		for (int d : docs) {
			cs += d + ",";
		}
		cs = cs.substring(0, cs.length() - 1);

		int typeid = 0;
		try {
			typeid = URIIDCache.getInstance().getURIID(
					"http://www.w3.org/1999/02/22-rdf-syntax-ns#type", false);
		} catch (Throwable e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		try {
			Connection conn = DBConnectionFactory.getConnection();// .getFalconConnection();
			PreparedStatement selpps = conn.prepareStatement("SELECT count(distinct p) FROM quadruple where doc_id in (?) and p!=?");
			selpps.setString(1, cs);
			selpps.setString(2, "u"+typeid);
			ResultSet selprs = selpps.executeQuery();
			if(selprs.next()){
				totalNum = selprs.getInt(1);
			}
			PreparedStatement selclassps = conn
					.prepareStatement("SELECT count(distinct p,o) FROM quadruple where doc_id in (?) and p='u"
							+ typeid + "'");
			selclassps.setString(1, cs);
			ResultSet selclassrs = selclassps.executeQuery();
			if(selclassrs.next()){
				totalNum += selclassrs.getInt(1);
			}
			selprs.close();
			selpps.close();

			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return totalNum;
	}
	public ArrayList<ArrayList<String>> getObjectProperties(){
		String cs = "";
		for (int d : docs) {
			cs += d + ",";
		}
		cs = cs.substring(0, cs.length() - 1);

		ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
		ArrayList<String> ps = new ArrayList<String>();

		int typeid = 0;
		try {
			typeid = URIIDCache.getInstance().getURIID(
					"http://www.w3.org/1999/02/22-rdf-syntax-ns#type", false);
		} catch (Throwable e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		try {
			Connection conn = DBConnectionFactory.getConnection();// .getFalconConnection();
			PreparedStatement selpps = conn
					.prepareStatement("SELECT distinct p FROM quadruple where doc_id in (?) and p!='u"
							+ typeid + "' and o like 'u%' ");
			selpps.setString(1, cs);
			ResultSet selprs = selpps.executeQuery();
			while (selprs.next()) {
				String pcode = selprs.getString(1);
				ps.add("u"
						+ URIIDCache.getInstance().getURI(
								Integer.parseInt(pcode.substring(1))));
			}
			selprs.close();
			selpps.close();

			for (String p : ps) {
				ArrayList<String> row = new ArrayList<String>();
				row.add("v1");
				row.add(p);
				row.add("v2");
				res.add(row);
			}
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Collections.sort(res, new Mycomparator());
		return res;
	}
	public ArrayList<ArrayList<String>> getProperties(){
		String cs = "";
		for (int d : docs) {
			cs += d + ",";
		}
		cs = cs.substring(0, cs.length() - 1);

		ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
		ArrayList<String> ps = new ArrayList<String>();

		int typeid = 0;
		try {
			typeid = URIIDCache.getInstance().getURIID(
					"http://www.w3.org/1999/02/22-rdf-syntax-ns#type", false);
		} catch (Throwable e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		try {
			Connection conn = DBConnectionFactory.getConnection();// .getFalconConnection();
			PreparedStatement selpps = conn
					.prepareStatement("SELECT distinct p FROM quadruple where doc_id in (?) and p!='u"
							+ typeid + "'");
			selpps.setString(1, cs);
			ResultSet selprs = selpps.executeQuery();
			while (selprs.next()) {
				String pcode = selprs.getString(1);
				ps.add("u"
						+ URIIDCache.getInstance().getURI(
								Integer.parseInt(pcode.substring(1))));
			}
			selprs.close();
			selpps.close();

			for (String p : ps) {
				ArrayList<String> row = new ArrayList<String>();
				row.add("v1");
				row.add(p);
				row.add("v2");
				res.add(row);
			}
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Collections.sort(res, new Mycomparator());
		return res;
	}
	public ArrayList<ArrayList<String>> getClasses(){
		String cs = "";
		for (int d : docs) {
			cs += d + ",";
		}
		cs = cs.substring(0, cs.length() - 1);
		
		int typeid = 0;
		try {
			typeid = URIIDCache.getInstance().getURIID(
					"http://www.w3.org/1999/02/22-rdf-syntax-ns#type", false);
		} catch (Throwable e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}		
		ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
		try {
			Connection conn = DBConnectionFactory.getConnection();// .getFalconConnection();
		PreparedStatement selclassps = conn
				.prepareStatement("SELECT distinct p,o FROM quadruple where doc_id in (?) and p='u"
						+ typeid + "'");
		selclassps.setString(1, cs);
		ResultSet selclassrs = selclassps.executeQuery();
		while (selclassrs.next()) {
			String pcode = selclassrs.getString(1);
			String ocode = selclassrs.getString(2);
			String p = "u"
					+ URIIDCache.getInstance().getURI(
							Integer.parseInt(pcode.substring(1)));
			if (ocode.startsWith("u")) {
				String o = "u"
						+ URIIDCache.getInstance().getURI(
								Integer.parseInt(ocode.substring(1)));
				ArrayList<String> row = new ArrayList<String>();
				row.add("v1");
				row.add(p);
				row.add(o);
				res.add(row);
			}

		}
		selclassrs.close();
		selclassps.close();
		conn.close();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (NumberFormatException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Throwable e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
		Collections.sort(res, new Mycomparator());
		return res;
	}
	public ArrayList<ArrayList<String>> getAll() {
		
		ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
		res.addAll(this.getClasses());
		res.addAll(this.getProperties());
			
		Collections.sort(res, new Mycomparator());
		return res;
	}
	public List<ArrayList<String>> getObjectProp(int start, int limit){
		ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
//		res.addAll(this.getClasses());
//		if(!(start<res.size() && limit<res.size()-start)){
			res.addAll(this.getObjectProperties());
//		}
		int end = (start+limit);
		end = end>res.size()?res.size():end;
		return res.subList(start, end);
		
	}

	public List<ArrayList<String>> getAll(int start, int limit){
		ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
		res.addAll(this.getClasses());
		if(!(start<res.size() && limit<res.size()-start)){
			res.addAll(this.getProperties());
		}
		int end = (start+limit);
		end = end>res.size()?res.size():end;
		return res.subList(start, end);
		
	}
	public static class Mycomparator implements Comparator<ArrayList<String>> {
		public int compare(ArrayList<String> o1, ArrayList<String> o2) {
			int a = o1.get(0).compareTo(o2.get(0));
			if (a == 0) {
				String o1p = Util.getLocalname(o1.get(1));
				String o2p = Util.getLocalname(o2.get(1));
				a = o1p.compareTo(o2p);
				if (a == 0) {
					a = o1.get(2).compareTo(o2.get(2));
				}
			}
			return a;
		}

	}
}
